/**
 * @(#)Record.java                 Oct 4, 2009 8:49:04 PM
 */
package com.radeonsys.litmus.data;

import com.radeonsys.litmus.data.schema.Schema;

/**
 * Represents a record of data containing fields which are structured as per a schema.
 * 
 * @author Ranganath Kini (ranganathkini at gmail dot com)
 * @version 1.0
 */
public interface Record {
	
	/**
	 * Returns the value of the field with the specified name as a string
	 * 
	 * @param fieldName	    the name of the field whose value is required
     * @param defaultValue  the value to be returned, in the event that no value was found for the field
	 * 
	 * @return	a {@link String} representing the value of the field
	 * 
	 * @throws FieldNotFoundException
	 * 			if there was no field found in the record with the specified
	 * 			name
	 */
	String getFieldValue(String fieldName, String defaultValue);
	
	/**
	 * Returns the value of the field with the specified name.
     *
     * <p>The type of the field value returned is inferred based on the caller</p>
	 * 
	 * @param fieldName		the name of the field whose value is required
     * @param defaultValue  the value to be returned, in the event that no value was found for the field
	 * 
	 * @return  the value of the field with the specified name
	 * 
	 * @throws FieldNotFoundException
	 * 			if there was no field found in the record with the specified
	 * 			name.
	 */
	<T> T getFieldValue(String fieldName, T defaultValue);
	
	/**
     * Returns the value of the field in this record with the specified name
     * 
	 * @param <T>       the type-parameter representing the type of the field's value as required
	 * 
	 * @param fieldName		the name of the field whose value is required
	 * 
	 * @param fieldType		a reference to the {@link Class} representing the type of the required field value.
     *                      This will override the field type specified in the {@link Schema} associated with
     *                      this record
	 * 
	 * @param defaultValue	the default value to return in case the field's value was not set
     *
	 * @return  the value of the field with the specified name cast to the specified type
     *
     * @throws FieldNotFoundException
	 * 			if there was no field found in the record with the specified
	 * 			name.
     * @throws ClassCastException
	 * 			if there was an error trying to convert the field's value to the specified type
	 */
	<T> T getFieldValue(String fieldName, Class<T> fieldType, T defaultValue);
	
	/**
     * Returns the schema used by this record
     *
	 * @return  a reference to an instance of {@link Schema} which is used by this record implementation
     *
     * @throws UnspecifiedSchemaException
     *          if there was not schema specified for this record implementation
	 */
	Schema getSchema();
}
